// Playground - noun: a place where people can play

import Cocoa


/*********************************************************************
 * The Swift Language Learning  Chapter 06: Functions
 *********************************************************************/



func sayHello(person:String) -> String {
	
	let greeting = "Hello, " + person + "!"
	
	return greeting
}

//sayHello(5) complie error, type don't match

sayHello("mary")



//External Parameter Names
func join(string s1:String, toString s2:String, withJoiner joiner:String = "_") -> String {
	
	return s1 + joiner + s2;
	
}

join(string: "a", toString: "b", withJoiner: "-")
join(string: "hello", toString: "world")


func containCharacter(#string: String, #characterToFind:Character)->Bool {//'#' is both for local parameter and extern parameter
	for c in string {
		if characterToFind == c {
			return true
		}
	}
	
	return false
}

let containAVee = containCharacter(string: "String", characterToFind: "p")

//inout value
func swapTwoInts(inout a: Int, inout b: Int) {
	let temporaryA = a
	a = b
	b = temporaryA
}

var someInt = 3
var anotherInt = 107
//swap(&2, &3) //error: “cannot pass a constant or a literal value as the argument”
swapTwoInts(&someInt, &anotherInt)
someInt
anotherInt


//closure
let names = ["Chris", "Alex", "Ewa", "Barry", "Daniella"]
func backwards(s1:String,s2:String) -> Bool {
	return s1 > s2
}

var reversed = sort(names, backwards)


var reversed2 = sort(names, {
		(s1:String,s2:String)->Bool in //closure express (compile error if change to other type,eg:'Int'. because swift know that names contain only Strings
		return s1 > s2
	})
reversed2

var reversed3 = sort(names, {
		s1,s2 in return s1 > s2 //“Inferring Type From Context”
	})
reversed3

var reversed4 = sort(names, {
		$0 > $1 
	})
reversed4


var reversed5 = sort(names){ //only when closure as last arguement
	$0 > $1
}
reversed5


let numbers = [5,3,7,9]
let strings = numbers.map{
	(var number) -> String in
	
	var output = "\(number)"
	
	return output
}
strings

//Capturing Values


func makeIncrementor(forIncrement amount: Int) -> () -> Int {
	var runningTotal = 0
	func incrementor() -> Int {
		runningTotal += amount
		return runningTotal
	}
	return incrementor
}

let inc1 = makeIncrementor(forIncrement:10) //copy runningTotal variable to a new heap
inc1()
inc1()
inc1()

let inc2 = makeIncrementor(forIncrement:10)
inc2()
let inc3 = inc2 //the same heap
inc3()













